package org.jiuling.wechat.publicplatform.api;

import org.jiuling.local.tools.exception.LocalToolsException;
import org.jiuling.local.tools.secretkey.MD5;
import org.jiuling.local.tools.verify.ObjectVerify;
import org.jiuling.local.tools.verify.StringVerify;
import org.jiuling.network.tools.http.request.exception.RequestException;
import org.jiuling.network.tools.http.request.model.HttpRequestBody;
import org.jiuling.network.tools.http.request.model.HttpRequestParam;
import org.jiuling.wechat.publicplatform.api.enums.Lang;
import org.jiuling.wechat.publicplatform.api.enums.WeChatApiEnum;
import org.jiuling.wechat.publicplatform.config.WeChatConfig;
import org.jiuling.wechat.publicplatform.exception.WeChatException;
import org.jiuling.wechat.publicplatform.model.*;
import org.jiuling.wechat.publicplatform.util.WeChatUtil;

import java.util.List;
import java.util.Map;

/**
 * 微信API接口
 * @author 紫灵
 * @date 2022年04月12日 22时16分50秒
 */
public class WeChatApi {

    /** 微信配置 */
    private final WeChatConfig weChatConfig;

    private AccessToken accessToken;

    /**
     * 设置AccessToken
     * @param accessToken 访问令牌
     */
    public void setAccessToken(AccessToken accessToken) {
        this.accessToken = accessToken;
    }

    /**
     * 微信API构造方法
     * @param weChatConfig 微信配置
     */
    public WeChatApi(WeChatConfig weChatConfig) {
        this.weChatConfig = weChatConfig;
    }

    /**
     * 获取AccessToken
     * <a href="https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html">https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html</a>
     * @return accessToken
     */
    public AccessToken getAccessToen() throws WeChatException {
        if(!ObjectVerify.isNull(accessToken)){
            return accessToken;
        }
        HttpRequestParam httpRequestParam = new HttpRequestParam()
                .add("grant_type","client_credential")
                .add("appid",weChatConfig.getAppId())
                .add("secret",weChatConfig.getSecret());
        return WeChatUtil.request(WeChatApiEnum.CGIBIN_TOKEN, httpRequestParam, null);
    }

    /**
     * 查询API限额
     * <a href="https://developers.weixin.qq.com/doc/offiaccount/openApi/get_api_quota.html">https://developers.weixin.qq.com/doc/offiaccount/openApi/get_api_quota.html</a>
     * @param apiUrl api地址
     * @return 限额
     */
    public Quota findOpenApiQuota(String apiUrl) throws WeChatException {
        try {
            HttpRequestParam httpRequestParam = new HttpRequestParam()
                    .add("access_token",getAccessToen().getToken());
            HttpRequestBody httpRequestBody = new HttpRequestBody()
                    .add("cgi_path",apiUrl);
            return WeChatUtil.request(WeChatApiEnum.CGIBIN_OPENAPI_QUOTA_GET, httpRequestParam, httpRequestBody);
        } catch (RequestException e) {
            throw new WeChatException(e.getLocalizedMessage());
        }
    }

    /**
     * 查询Rid
     * <a href="https://developers.weixin.qq.com/doc/offiaccount/openApi/get_rid_info.html">https://developers.weixin.qq.com/doc/offiaccount/openApi/get_rid_info.html</a>
     * @param rid rid
     * @return rid信息
     */
    public RidInfo findRidInfo(String rid) throws WeChatException {
        try {
            HttpRequestParam httpRequestParam = new HttpRequestParam()
                    .add("access_token",getAccessToen().getToken());
            HttpRequestBody httpRequestBody = new HttpRequestBody()
                    .add("rid",rid);
            return WeChatUtil.request(WeChatApiEnum.CGIBIN_OPENAPI_RID_GET, httpRequestParam, httpRequestBody);
        } catch (RequestException e) {
            throw new WeChatException(e.getLocalizedMessage());
        }
    }

    /**
     * 清楚限额
     * <a href="https://developers.weixin.qq.com/doc/offiaccount/openApi/clear_quota.html">https://developers.weixin.qq.com/doc/offiaccount/openApi/clear_quota.html</a>
     * @throws WeChatException 微信限额
     */
    public Boolean clearQuota() throws WeChatException {
        try {
            HttpRequestParam httpRequestParam = new HttpRequestParam()
                    .add("access_token", getAccessToen().getToken());
            HttpRequestBody httpRequestBody = new HttpRequestBody()
                    .add("appid", weChatConfig.getAppId());
            return WeChatUtil.request(WeChatApiEnum.CGIBIN_CLEARQUOTA,httpRequestParam,httpRequestBody);
        } catch (RequestException e) {
            throw new WeChatException(e.getLocalizedMessage());
        }
    }

    /**
     * 获取api区域Ip
     * <a href="https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_the_WeChat_server_IP_address.html">https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_the_WeChat_server_IP_address.html</a>
     * @return Api列表
     * @throws WeChatException 微信异常
     */
    public List<String> getApiDomainIp() throws WeChatException {
        HttpRequestParam httpRequestParam = new HttpRequestParam()
                .add("access_token",getAccessToen().getToken());
        return WeChatUtil.request(WeChatApiEnum.GET_API_DOMAIN_IP,httpRequestParam,null);
    }

    /**
     * 获取用户列表
     * @param nextOpenid 第一个拉去的openid
     * @return
     * @throws WeChatException
     */
    public OpenIdList getUser(String nextOpenid) throws WeChatException {
        HttpRequestParam httpRequestParam = new HttpRequestParam()
                .add("access_token",getAccessToen().getToken());
        // 如果存在第一个拉取的OPENID则添加该参数
        if(!StringVerify.isBlank(nextOpenid)){
            httpRequestParam.add("next_openid",nextOpenid);
        }
        return WeChatUtil.request(WeChatApiEnum.GET_USER,httpRequestParam,null);
    }

    /**
     * 获取用户信息
     * @param openId 开放id
     * @param lang 语言
     * @throws WeChatException 微信异常
     */
    public UserInfo findUserInfo(String openId, Lang lang) throws WeChatException {
        HttpRequestParam httpRequestParam = new HttpRequestParam()
                .add("access_token",getAccessToen().getToken())
                .add("openid",openId);
        if(!ObjectVerify.isNull(lang)){
            httpRequestParam.add("lang",lang.getCode());
        }
        return WeChatUtil.request(WeChatApiEnum.USER_INFO,httpRequestParam,null);
    }

    /**
     * 发送模板消息
     * @param touser 接收者openid
     * @param templateId 模板ID
     * @param url 模板跳转链接（海外帐号没有跳转能力）
     * @param miniProgram 跳小程序所需数据，不需跳小程序可不用传该数据
     * @param data 模板数据
     * @return 消息id
     * @throws WeChatException
     */
    public String sendTemplateMessage(String touser, String templateId, String url, MiniProgram miniProgram, Map<String,Object> data) throws WeChatException {
        HttpRequestParam httpRequestParam = new HttpRequestParam()
                .add("access_token",getAccessToen().getToken());
        try {
            HttpRequestBody httpRequestBody = new HttpRequestBody()
                    .add("touser",touser)
                    .add("template_id",templateId)
                    .add("data",data);
            if(!StringVerify.isBlank(url)){
                httpRequestBody.add("url",url);
            }
            return WeChatUtil.request(WeChatApiEnum.MESSAGE_TEMPLATE_SEND,httpRequestParam,httpRequestBody);
        }catch (RequestException e){
            throw new WeChatException(e.getLocalizedMessage());
        }

    }

    public static void main(String[] args) throws LocalToolsException,  WeChatException {
        System.out.println(MD5.getMd5("123456"));
//        WeChatApi weChatApi = new WeChatApi(new WeChatConfig.Builder()
//                .addAppId("wx31852005efca7df1")
//                .addSecret("764e5b4807477808d71c738434ff00e3")
//                .builder());
//        AccessToken accessToken = new AccessToken();
//        accessToken.setToken("56_ove6N7zt2DApIOz2ou1ShrkbTXQXKHZ2bmpXXjCbEmH_GZrgDHxV99FR7X3VNOG3iYrBn-yiDWaa4o7de3UkuMQGgmj4X6I9hY_5zA8_GVGXKKF2zcAIXBXP_oiCA--mrbfJNMP6APoKLSxHOSZeAIAZDK");
//        accessToken.setExpiresIn(7200);
//        weChatApi.setAccessToken(accessToken);
//        String openId = "oygYj1SLrraYTklHMgZ3DWxClaVM";
////        f_XspW62w35IT9V1_NppUiskNaXl0pitdqPXsLH0roc
//        Map<String,Object> data = new HashMap<>();
//        Map<String,Object> first = new HashMap<>();
//        first.put("value","测试");
//        first.put("color","#173177");
//        data.put("first",first);
//        Map<String,Object> keyword1 = new HashMap<>();
//        keyword1.put("value","测试1");
//        keyword1.put("color","#173177");
//        data.put("keyword1",keyword1);
//        Map<String,Object> keyword2 = new HashMap<>();
//        keyword2.put("value","测试2");
//        keyword2.put("color","#173177");
//        data.put("keyword2",keyword2);
//        Map<String,Object> keyword3 = new HashMap<>();
//        keyword3.put("value","测试3");
//        keyword3.put("color","#173177");
//        data.put("keyword3",keyword3);
//        System.out.println(JSON.toJSONString(weChatApi.sendTemplateMessage(openId,"f_XspW62w35IT9V1_NppUiskNaXl0pitdqPXsLH0roc",null,null,data)));
//        System.out.println(JSON.toJSONString(weChatApi.findUserInfo(openId,null).getSubscribeScene().getName()));
//        weChatApi.clearQuota();
//        System.out.println(JSON.toJSONString());
//        System.out.println(JSON.toJSONString(System.getProperties().getProperty("user.country")));
    }
}
